package com.funsport.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.funsport.entity.Event;
import com.funsport.entity.EventSignup;
import com.funsport.entity.VenueBooking;
import com.funsport.mapper.EventMapper;
import com.funsport.mapper.EventSignupMapper;
import com.funsport.mapper.VenueBookingMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 定时提醒任务
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ReminderScheduler {
    
    private final EventMapper eventMapper;
    private final EventSignupMapper eventSignupMapper;
    private final VenueBookingMapper venueBookingMapper;
    private final NotificationService notificationService;
    
    /**
     * 活动前1小时提醒
     * 每小时执行一次
     */
    @Scheduled(cron = "0 0 * * * ?")
    public void sendEventReminders() {
        log.info("开始执行活动提醒任务");
        
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime oneHourLater = now.plusHours(1);
        
        // 查询1小时后开始的活动
        LambdaQueryWrapper<Event> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(Event::getStartTime, now)
               .le(Event::getStartTime, oneHourLater)
               .eq(Event::getStatus, "PUBLISHED");
        
        List<Event> events = eventMapper.selectList(wrapper);
        
        for (Event event : events) {
            // 获取该活动的所有报名用户
            LambdaQueryWrapper<EventSignup> signupWrapper = new LambdaQueryWrapper<>();
            signupWrapper.eq(EventSignup::getEventId, event.getId())
                        .eq(EventSignup::getStatus, "approved");
            
            List<EventSignup> signups = eventSignupMapper.selectList(signupWrapper);
            
            // 给每个用户发送提醒
            for (EventSignup signup : signups) {
                try {
                    notificationService.sendEventReminder(
                        signup.getUserId(),
                        event.getId(),
                        event.getTitle(),
                        event.getStartTime()
                    );
                } catch (Exception e) {
                    log.error("发送活动提醒失败: eventId={}, userId={}", event.getId(), signup.getUserId(), e);
                }
            }
        }
        
        log.info("活动提醒任务完成: 处理了 {} 个活动", events.size());
    }
    
    /**
     * 场地预订前1天提醒
     * 每天早上9点执行
     */
    @Scheduled(cron = "0 0 9 * * ?")
    public void sendBookingReminders() {
        log.info("开始执行预订提醒任务");
        
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime tomorrow = now.plusDays(1);
        
        // 查询明天的预订
        LambdaQueryWrapper<VenueBooking> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(VenueBooking::getStartTime, tomorrow.toLocalDate().atStartOfDay())
               .lt(VenueBooking::getStartTime, tomorrow.toLocalDate().plusDays(1).atStartOfDay())
               .eq(VenueBooking::getStatus, "confirmed");
        
        List<VenueBooking> bookings = venueBookingMapper.selectList(wrapper);
        
        for (VenueBooking booking : bookings) {
            try {
                // 这里简化处理，实际应该查询场地名称
                notificationService.sendBookingReminder(
                    booking.getUserId(),
                    booking.getId(),
                    "场地" + booking.getVenueId(),
                    booking.getStartTime()
                );
            } catch (Exception e) {
                log.error("发送预订提醒失败: bookingId={}, userId={}", booking.getId(), booking.getUserId(), e);
            }
        }
        
        log.info("预订提醒任务完成: 处理了 {} 个预订", bookings.size());
    }
    
    /**
     * 清理过期通知
     * 每周日凌晨2点执行
     */
    @Scheduled(cron = "0 0 2 ? * SUN")
    public void cleanExpiredNotifications() {
        log.info("开始清理过期通知");
        
        // 删除30天前的已读通知
        LocalDateTime thirtyDaysAgo = LocalDateTime.now().minusDays(30);
        
        // 这里应该调用NotificationMapper删除，简化处理
        log.info("清理过期通知完成");
    }
}

